﻿//by  张海军 710605420@qq.com
using System;
using System.Collections.Generic;
using UnityEngine;
using LazyFramework;
using Unity.Burst;

namespace LazyFramework
{
    public delegate void Handler();
    public delegate void Handler<T1>(T1 param1);
    public delegate void Handler<T1, T2>(T1 param1, T2 param2);
    public delegate void Handler<T1, T2, T3>(T1 param1, T2 param2, T3 param3);
    public interface IAnimatable
    {
        void AdvanceTime();
    }
    /**时钟管理器[同一函数多次计时，默认会被后者覆盖,delay小于1会立即执行]*/
    public class TimerManager : Singleton<TimerManager>, IAnimatable
    {
        List<uint> timerIds = new List<uint>();
        public static List<IAnimatable> timerList = new List<IAnimatable>();

        public TimerManager()
        {
            timerList.Add(this);
        }

        private List<TimerHandler> _pool = new List<TimerHandler>();
        /** 用数组保证按放入顺序执行*/
        private List<TimerHandler> _handlers = new List<TimerHandler>();
        private int _currFrame = 0;
        private uint _index = 0;

        public void AdvanceTime()
        {
            _currFrame++;
            for (int i = 0; i < _handlers.Count; i++)
            {
                TimerHandler handler = _handlers[i];
                long t = handler.userFrame ? _currFrame : currentTime;
                if (t >= handler.exeTime)
                {
                    Delegate method = handler.method;
                    object[] args = handler.args;
                    if (handler.repeat)
                    {
                        while (t >= handler.exeTime)
                        {
                            handler.exeTime += handler.delay;
                            if (args == null || args.Length ==0)
                            {
                                Handler function = (Handler)method;
                                function();
                            }
                            else
                            {
                                method.DynamicInvoke(args);
                            }
                        }
                    }
                    else
                    {
                        clear(handler.method);
                        method.DynamicInvoke(args);
                    }
                }
            }
        }

        private uint GetTimerID()
        {
            timerIds.Sort((val1, val2) =>
            {
                return (int)(val1 - val2);
            });
            if (timerIds.Count == 0)
                return 1;
            int i = 0;
            int j = 1;
            while(true)
            {
                if( j< timerIds.Count && (timerIds[j]-timerIds[i]  == 1))
                {
                    i++;
                    j++;
                }else
                {
                    return timerIds[i] + 1;
                }
            }
        }

        private uint create(bool useFrame, bool repeat, int delay, Delegate method, params object[] args)
        {
            if (method == null)
            {
                return 0;
            }

            //如果执行时间小于1，直接执行
            if (delay < 1)
            {
                method.DynamicInvoke(args);
                return 0;
            }
            TimerHandler handler;
            if (_pool.Count > 0)
            {
                handler = _pool[_pool.Count - 1];
                _pool.Remove(handler);
            }
            else
            {
                handler = new TimerHandler();
            }
            handler.id = GetTimerID();
            handler.userFrame = useFrame;
            handler.repeat = repeat;
            handler.delay = delay;
            handler.method = method;
            handler.args = args;
            handler.exeTime = delay + (useFrame ? _currFrame : currentTime);
            _handlers.Add(handler);
            return handler.id;
        }

        /// /// <summary>
        /// 定时执行一次(基于毫秒)
        /// </summary>
        /// <param name="delay">延迟时间(单位毫秒)</param>
        /// <param name="method">结束时的回调方法</param>
        /// <param name="args">回调参数</param>
        public uint doOnce(int delay, Handler method)
        {
            return create(false, false, delay, method);
        }
        public uint doOnce<T1>(int delay, Handler<T1> method, params object[] args)
        {
           return create(false, false, delay, method, args);
        }
        public uint doOnce<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)
        {
            return create(false, false, delay, method, args);
        }
        public uint doOnce<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)
        {
            return create(false, false, delay, method, args);
        }

        /// /// <summary>
        /// 定时重复执行(基于毫秒)
        /// </summary>
        /// <param name="delay">延迟时间(单位毫秒)</param>
        /// <param name="method">结束时的回调方法</param>
        /// <param name="args">回调参数</param>
        public uint doLoop(int delay, Handler method)
        {
            return create(false, true, delay, method);
        }
        public uint doLoop<T1>(int delay, Handler<T1> method, params object[] args)
        {
            return create(false, true, delay, method, args);
        }
        public uint doLoop<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)
        {
            return create(false, true, delay, method, args);
        }
        public uint doLoop<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)
        {
            return create(false, true, delay, method, args);
        }


        /// <summary>
        /// 定时执行一次(基于帧率)
        /// </summary>
        /// <param name="delay">延迟时间(单位为帧)</param>
        /// <param name="method">结束时的回调方法</param>
        /// <param name="args">回调参数</param>
        public uint doFrameOnce(int delay, Handler method)
        {
            return create(true, false, delay, method);
        }
        public uint doFrameOnce<T1>(int delay, Handler<T1> method, params object[] args)
        {
            return create(true, false, delay, method, args);
        }
        public uint doFrameOnce<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)
        {
            return create(true, false, delay, method, args);
        }
        public uint doFrameOnce<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)
        {
            return create(true, false, delay, method, args);
        }

        /// <summary>
        /// 定时重复执行(基于帧率)
        /// </summary>
        /// <param name="delay">延迟时间(单位为帧)</param>
        /// <param name="method">结束时的回调方法</param>
        /// <param name="args">回调参数</param>
        public uint doFrameLoop(int delay, Handler method)
        {
            return create(true, true, delay, method);
        }
        public uint doFrameLoop<T1>(int delay, Handler<T1> method, params object[] args)
        {
            return create(true, true, delay, method, args);
        }
        public uint doFrameLoop<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)
        {
            return create(true, true, delay, method, args);
        }
        public uint doFrameLoop<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)
        {
            return create(true, true, delay, method, args);
        }

        /// <summary>
        /// 清理定时器
        /// </summary>
        /// <param name="method">method为回调函数本身</param>
        public void clearTimer(Handler method)
        {
            clear(method);
        }
        public void clearTimer<T1>(Handler<T1> method)
        {
            clear(method);
        }
        public void clearTimer<T1, T2>(Handler<T1, T2> method)
        {
            clear(method);
        }
        public void clearTimer<T1, T2, T3>(Handler<T1, T2, T3> method)
        {
            clear(method);
        }

        private void clear(Delegate method)
        {
            TimerHandler handler = null;
            for (int i = 0; i < _handlers.Count; ++i)
            {
                if (_handlers[i].method == method)
                {
                    handler = _handlers[i];
                    break;
                }
            }
            if (handler != null)
            {
                _handlers.Remove(handler);
                handler.clear();
                _pool.Add(handler);
            }
        }

        public void Kill(uint timerID)
        {
            TimerHandler handler = null;
            for (int i = 0; i < _handlers.Count; ++i)
            {
                if (_handlers[i].id == timerID)
                {
                    handler = _handlers[i];
                    break;
                }
            }
            if (handler != null)
            {
                _handlers.Remove(handler);
                handler.clear();
                _pool.Add(handler);
            }
        }

        /// <summary>
        /// 清理所有定时器
        /// </summary>
        public void clearAllTimer()
        {
            foreach (TimerHandler handler in _handlers)
            {
                clear(handler.method);
                clearAllTimer();
                return;
            }
        }

        public static void RemoveTimerMgr(TimerManager timerMgr)
        {
            timerList.Remove(timerMgr);
        }

        /// <summary>
        /// 游戏自启动运行时间，毫秒
        /// </summary>
        public long currentTime
        {
            get { return (long)(Time.time * 1000); }
        }

        /**定时处理器*/

        private class TimerHandler
        {
            /**唯一ID*/
            public uint id;
            /**执行间隔*/
            public int delay;
            /**是否重复执行*/
            public bool repeat;
            /**是否用帧率*/
            public bool userFrame;

            /**执行时间*/
            public long exeTime;

            /**处理方法*/
            public Delegate method;

            /**参数*/
            public object[] args;

            /**清理*/

            public void clear()
            {
                id = 0;
                method = null;
                args = null;
            }
        }
    }
}
